import net.sourceforge.rconed.SourceRcon;

/** Class designed to interact with Valve Dedicated Source server</br>
 * That class is based on SourceRcon class</br>
 * made by oscahie (aka PiTaGoRaS)</br>
 * Version: 0.1</br>
 * Contact me : gauvrit.alexandre@gmail.com</br>
 */

public class ServerSource extends SourceRcon {

	// 	 Vars for demo recording
	boolean firsthalf=true;
	int cptdemo=0;

	///	 Default values for debugging

	private String servername="";
	private String ipserver="127.0.0.1";
	private String password ="passfnf";
	private int port=27015;
	private int localPort=27015;


	/** Constructor of ServerSource class, including parameters</br>
	 * 
	 * @param name_server    	Name of the server
	 * @param ip      			IP of the server
	 * @param rconpass  		The RCON password.
	 * @param svport   			The port of the server
	 */
	public ServerSource(String name_server, String ip, String rconpass, int svport) {

		super();		
		this.servername=name_server;
		this.ipserver=ip;
		this.password=rconpass;
		this.port=svport;
	}

	/** Constructor of ServerSource class, with default parameters</br>
	 * 
	 * ONLY FOR DEBUG !</br>
	 * Use Source_init if you want to initialise later</br>
	 */
	public ServerSource() {
		super();		
		System.out.println("WARNING - DEFAULT SERVER ");
	}

	/** Basic method to send command to the server</br>
	 * 
	 * @param command 	the command to send
	 * @return the result of the command (String)
	 */
	private String Source_send(String command){
		String buffer="";
		try{
			buffer = SourceRcon.send(this.ipserver, this.port, this.password,command);
		}
		catch(Exception e){ 
			// Envoyer sur la sortie debug;
		};
		return buffer;
	}

	/** Basic method to send command to the server with output port</br>
	 * 
	 * @param command 	the command to send
	 * @param port 		the port used to send the command
	 * @return the result of the command (String)
	 */
	private String Source_send(String command,int port){
		String buffer="";
		if(port!=27015){
			localPort=port;
		}
		try{
			buffer = SourceRcon.send(this.ipserver, this.port, this.password,command,this.localPort);
		}
		catch(Exception e){ 
			// Envoyer sur la sortie debug;
		};
		return buffer;
	}


	/** Method to change the map on the server</br>
	 * 
	 * @param map 	name of the map
	 */
	public void Source_changemap(String map){
		String cmdmap = "changelevel "+map;
		try{
			Source_send(cmdmap);
			Thread.sleep(10000);
		}catch(Exception e){
			//	Envoyer sur la sortie debug;
		};
	}


	/** Method to change the name of the server</br>
	 * 
	 * @param name 	the name of the server
	 */
	// change le nom du serveur
	public void Source_changeservername(String name){
		String cmdname = "sv_hostname"+name;
		try{
			Source_send(cmdname);
		}catch(Exception e){
			//	Envoyer sur la sortie debug;
		};
	}


	/** Method to change the password of the server</br>
	 * 
	 * @param passwd 	the new password of the server (not the rcon)
	 */
	public void Source_changepass(String passwd)
	{
		String cmdpasswd="sv_password "+passwd;
		try{
			Source_send(cmdpasswd);
			Thread.sleep(3000);
		}catch(Exception e){
			//	Envoyer sur la sortie debug;
		};
	}


	/** Method to restart the server</br>
	 * The server is restarted and the method</br>
	 * make the program sleep for 5secs</br>
	 */
	public void Source_restartserver(){
		String cmdrs="_restart";
		try{
			Source_send(cmdrs);
			Thread.sleep(5000);
		}catch(Exception e){
			//	Envoyer sur la sortie debug;
		};
	}


	/** Method to restart scores and games 3 times</br>
	 * 
	 * As usually in competition, that method restart</br>
	 * the scores and rounds 3 times to get teams</br> 
	 * prepared</br>
	 */
	public void Source_restartround(){
		String cmdrs="mp_restartgame 3";
		try{
			Source_send(cmdrs);
			Thread.sleep(3000);
		}catch(Exception e){
			//	Envoyer sur la sortie debug;
		};
	}


	/** Method to restart scores and games 3 times</br>
	 * 
	 * As usually in competition, that method restart</br>
	 * the scores and rounds 3 times to get teams</br> 
	 * prepared</br>
	 */
	public void Source_restartroundthree(){
		String cmdrs="mp_restartgame 3";
		try{
			Source_send(cmdrs);
			Thread.sleep(3000);
			Source_send(cmdrs);
			Thread.sleep(3000);
			Source_send(cmdrs);
			Thread.sleep(3000);
		}catch(Exception e){
			//	Envoyer sur la sortie debug;
		};
	}


	/** Method to get status of the game</br>
	 * 
	 * That method returns the status of the game</br>
	 * name + map + player_id + names + ping .. etc </br>
	 */
	public void Source_getstatus(){
		String returnstatus="";
		String cmdstatus="status";
		try{
			returnstatus = Source_send(cmdstatus);
		}
		catch(Exception e){};
		if(returnstatus!=null){
			System.out.println(returnstatus);
		}
	}


	/** Method to launch a match </br>
	 * 
	 * That method first change the map (using Source_changemap)</br>
	 * then start record the game</br>
	 * change the password</br>
	 * restart scores and money</br>
	 * 
	 * @param map		Name of the map
	 * @param passwd	New password of the map
	 * @param record	Record or not the game
	 */
	public void Source_launchmatch(String map,String passwd, boolean record){
		String recordname="";
		if(record==true){
			if(firsthalf==true){recordname="record-"+ servername +"-"+map+"-firsthalf"+".dem";}
			else{ recordname="record-"+ servername +map+"-secondhalf"+".dem";}
		}
		this.Source_changemap(map);
		this.Source_record(recordname);
		this.Source_changepass(passwd);
		this.Source_restartround();
	}



	/** Method to launch a match </br>
	 * 
	 * That method first change the map (using Source_changemap)</br>
	 * then start record the game</br>
	 * restart scores and money</br>
	 * 
	 * @param map		Name of the map
	 * @param record	Record or not the game
	 */
	public void Source_launchmatch(String map, boolean record){
		String recordname="";
		if(record==true){
			if(firsthalf==true){recordname="record-"+ servername +"-"+map+"-firsthalf"+".dem";}
			else{ recordname="record-"+ servername +map+"-secondhalf"+".dem";}
		}
		this.Source_changemap(map);
		this.Source_record(recordname);
		this.Source_restartround();
	}

	/** Method to start recording </br>
	 * 
	 * @param rcname	Name of the record</br>
	 * </br>if the record name is not precized, 
	 * </br>default demo name is applied
	 */	


	// Lance l'enregistrement du match
	private void Source_record( String rcname ) {

		// TODO assurer le source_tv ( delay etc : http://developer.valvesoftware.com/wiki/SourceTV

		if(rcname==null){rcname="demodefault"+cptdemo;}
		try{
			Source_send(rcname);
		}catch(Exception e){
			//	Envoyer sur la sortie debug;
		};

	}
}
